From: awilliam@xenbuild.aw Date: Wed, 24 May 2006 16:56:47 +0000 (-0600) Subject: [IA64] GNTMAP_readonly support xen part X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~16032 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=4e91ee946ff5dfedb08a684bc1384aa966061f42;p=xen.git [IA64] GNTMAP_readonly support xen part add grant table GNTMAP_readonly support. introduce ASSIGN_readonly flags for read only page assignment to pseudo physical address space. Signed-off-by: Isaku Yamahata --- diff --git a/xen/arch/ia64/vmx/vmx_init.c b/xen/arch/ia64/vmx/vmx_init.c index e3fb857e26..85220890f5 100644 --- a/xen/arch/ia64/vmx/vmx_init.c +++ b/xen/arch/ia64/vmx/vmx_init.c @@ -346,7 +346,7 @@ int vmx_build_physmap_table(struct domain *d) for (j = io_ranges[i].start; j < io_ranges[i].start + io_ranges[i].size; j += PAGE_SIZE) - __assign_domain_page(d, j, io_ranges[i].type); + __assign_domain_page(d, j, io_ranges[i].type, ASSIGN_writable); } /* Map normal memory below 3G */ diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index bff2e85500..16af32d186 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -834,17 +834,19 @@ assign_new_domain0_page(struct domain *d, unsigned long mpaddr) } /* map a physical address to the specified metaphysical addr */ +// flags: currently only ASSIGN_readonly void __assign_domain_page(struct domain *d, - unsigned long mpaddr, unsigned long physaddr) + unsigned long mpaddr, unsigned long physaddr, + unsigned long flags) { pte_t *pte; + unsigned long arflags = (flags & ASSIGN_readonly)? _PAGE_AR_R: _PAGE_AR_RWX; pte = lookup_alloc_domain_pte(d, mpaddr); if (pte_none(*pte)) { - set_pte(pte, - pfn_pte(physaddr >> PAGE_SHIFT, - __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX))); + set_pte(pte, pfn_pte(physaddr >> PAGE_SHIFT, + __pgprot(__DIRTY_BITS | _PAGE_PL_2 | arflags))); mb (); } else printk("%s: mpaddr %lx already mapped!\n", __func__, mpaddr); @@ -861,7 +863,7 @@ assign_domain_page(struct domain *d, BUG_ON((physaddr & GPFN_IO_MASK) != GPFN_MEM); ret = get_page(page, d); BUG_ON(ret == 0); - __assign_domain_page(d, mpaddr, physaddr); + __assign_domain_page(d, mpaddr, physaddr, ASSIGN_writable); //XXX CONFIG_XEN_IA64_DOM0_VP // TODO racy @@ -871,12 +873,12 @@ assign_domain_page(struct domain *d, #ifdef CONFIG_XEN_IA64_DOM0_VP static void assign_domain_same_page(struct domain *d, - unsigned long mpaddr, unsigned long size) + unsigned long mpaddr, unsigned long size) { //XXX optimization unsigned long end = mpaddr + size; for (; mpaddr < end; mpaddr += PAGE_SIZE) { - __assign_domain_page(d, mpaddr, mpaddr); + __assign_domain_page(d, mpaddr, mpaddr, ASSIGN_writable); } } @@ -1113,15 +1115,14 @@ unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr) } pteval = pfn_pte(mpaddr >> PAGE_SHIFT, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)); - pte = &pteval; - return *(unsigned long *)pte; + return pte_val(pteval); } #endif pte = lookup_noalloc_domain_pte(d, mpaddr); if (pte != NULL) { if (pte_present(*pte)) { //printk("lookup_domain_page: found mapping for %lx, pte=%lx\n",mpaddr,pte_val(*pte)); - return *(unsigned long *)pte; + return pte_val(*pte); } else if (VMX_DOMAIN(d->vcpu[0])) return GPFN_INV_MASK; } @@ -1135,7 +1136,10 @@ unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr) printk("%s: bad mpa 0x%lx (=> 0x%lx)\n", __func__, mpaddr, (unsigned long)d->max_pages << PAGE_SHIFT); mpafoo(mpaddr); - return 0; + + //XXX This is a work around until the emulation memory access to a region + // where memory or device are attached is implemented. + return pte_val(pfn_pte(0, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX))); } #ifdef CONFIG_XEN_IA64_DOM0_VP @@ -1159,19 +1163,21 @@ out: // caller must get_page(mfn_to_page(mfn)) before // caller must call set_gpfn_from_mfn(). +// flags: currently only ASSIGN_readonly static void assign_domain_page_replace(struct domain *d, unsigned long mpaddr, - unsigned long mfn, unsigned int flags) + unsigned long mfn, unsigned long flags) { struct mm_struct *mm = &d->arch.mm; pte_t* pte; pte_t old_pte; pte_t npte; + unsigned long arflags = (flags & ASSIGN_readonly)? _PAGE_AR_R: _PAGE_AR_RWX; pte = lookup_alloc_domain_pte(d, mpaddr); // update pte - npte = pfn_pte(mfn, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)); + npte = pfn_pte(mfn, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | arflags)); old_pte = ptep_xchg(mm, mpaddr, pte, npte); if (!pte_none(old_pte)) { unsigned long old_mfn; @@ -1200,11 +1206,11 @@ assign_domain_page_replace(struct domain *d, unsigned long mpaddr, unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, - unsigned int flags, domid_t domid) + unsigned long flags, domid_t domid) { int error = 0; - struct domain* rd; + rd = find_domain_by_id(domid); if (unlikely(rd == NULL)) { switch (domid) { @@ -1234,7 +1240,7 @@ dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, goto out1; } - assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* flags:XXX */); + assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, flags); //don't update p2m table because this page belongs to rd, not d. out1: put_domain(rd); @@ -1254,23 +1260,18 @@ create_grant_host_mapping(unsigned long gpaddr, struct page_info* page; int ret; - if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) { + if (flags & (GNTMAP_device_map | + GNTMAP_application_map | GNTMAP_contains_pte)) { DPRINTK("%s: flags 0x%x\n", __func__, flags); return GNTST_general_error; } - if (flags & GNTMAP_readonly) { -#if 0 - DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n", - __func__, flags); -#endif - flags &= ~GNTMAP_readonly; - } page = mfn_to_page(mfn); ret = get_page(page, page_get_owner(page)); BUG_ON(ret == 0); - assign_domain_page_replace(d, gpaddr, mfn, flags); + assign_domain_page_replace(d, gpaddr, mfn, (flags & GNTMAP_readonly)? + ASSIGN_readonly: ASSIGN_writable); return GNTST_okay; } @@ -1289,22 +1290,17 @@ destroy_grant_host_mapping(unsigned long gpaddr, DPRINTK("%s: flags 0x%x\n", __func__, flags); return GNTST_general_error; } - if (flags & GNTMAP_readonly) { -#if 0 - DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n", - __func__, flags); -#endif - flags &= ~GNTMAP_readonly; - } pte = lookup_noalloc_domain_pte(d, gpaddr); if (pte == NULL || !pte_present(*pte) || pte_pfn(*pte) != mfn) - return GNTST_general_error;//XXX GNTST_bad_pseudo_phys_addr + return GNTST_general_error; // update pte old_pte = ptep_get_and_clear(&d->arch.mm, gpaddr, pte); if (pte_present(old_pte)) { - old_mfn = pte_pfn(old_pte);//XXX + old_mfn = pte_pfn(old_pte); + } else { + return GNTST_general_error; } domain_page_flush(d, gpaddr, old_mfn, INVALID_MFN); @@ -1405,7 +1401,7 @@ guest_physmap_add_page(struct domain *d, unsigned long gpfn, ret = get_page(mfn_to_page(mfn), d); BUG_ON(ret == 0); - assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* XXX */); + assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, ASSIGN_writable); set_gpfn_from_mfn(mfn, gpfn);//XXX SMP //BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> PAGE_SHIFT)); diff --git a/xen/arch/ia64/xen/process.c b/xen/arch/ia64/xen/process.c index 6448901988..3e88ad1662 100644 --- a/xen/arch/ia64/xen/process.c +++ b/xen/arch/ia64/xen/process.c @@ -85,6 +85,8 @@ u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__, u64* logps) struct domain *d = current->domain; ia64_itir_t itir = {.itir = itir__}; u64 mask, mpaddr, pteval2; + u64 arflags; + u64 arflags2; pteval &= ((1UL << 53) - 1);// ignore [63:53] bits @@ -123,6 +125,20 @@ u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__, u64* logps) } #endif pteval2 = lookup_domain_mpa(d,mpaddr); + arflags = pteval & _PAGE_AR_MASK; + arflags2 = pteval2 & _PAGE_AR_MASK; + if (arflags != _PAGE_AR_R && arflags2 == _PAGE_AR_R) { +#if 0 + DPRINTK("%s:%d " + "pteval 0x%lx arflag 0x%lx address 0x%lx itir 0x%lx " + "pteval2 0x%lx arflags2 0x%lx mpaddr 0x%lx\n", + __func__, __LINE__, + pteval, arflags, address, itir__, + pteval2, arflags2, mpaddr); +#endif + pteval = (pteval & ~_PAGE_AR_MASK) | _PAGE_AR_R; +} + pteval2 &= _PAGE_PPN_MASK; // ignore non-addr bits pteval2 |= (pteval & _PAGE_ED); pteval2 |= _PAGE_PL_2; // force PL0->2 (PL3 is unaffected) diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index 31ec0b9d87..679de155ad 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -114,7 +114,7 @@ struct arch_vcpu { struct page_info * assign_new_domain_page(struct domain *d, unsigned long mpaddr); void assign_new_domain0_page(struct domain *d, unsigned long mpaddr); -void __assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr); +void __assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr, unsigned long flags); void assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr); void assign_domain_io_page(struct domain *d, unsigned long mpaddr, unsigned long flags); #ifdef CONFIG_XEN_IA64_DOM0_VP @@ -123,7 +123,7 @@ unsigned long assign_domain_mmio_page(struct domain *d, unsigned long mpaddr, un unsigned long assign_domain_mach_page(struct domain *d, unsigned long mpaddr, unsigned long size); unsigned long do_dom0vp_op(unsigned long cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3); unsigned long dom0vp_zap_physmap(struct domain *d, unsigned long gpfn, unsigned int extent_order); -unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, unsigned int flags, domid_t domid); +unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, unsigned long flags, domid_t domid); #else #define alloc_dom_xen_and_dom_io() do { } while (0) #endif diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index 7788f00349..b7e5d2b662 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -369,6 +369,10 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); #define IA64_DOM0VP_add_physmap 18 // assigne machine page frane // to dom0's pseudo physical // address space. +// flags for page assignement to pseudo physical address space +#define _ASSIGN_readonly 0 +#define ASSIGN_readonly (1UL << _ASSIGN_readonly) +#define ASSIGN_writable (0UL << _ASSIGN_readonly) // dummy flag #endif /* !__ASSEMBLY__ */